var MMM_INCOMPAT = false;
function MMMCheckCompatible() {
  if (MMM_INCOMPAT) 
    return false;
  if (!window.RegExp) 
    return false;
  var AGENTS = ["opera","msie","safari","firefox","netscape","mozilla"];
  var agent = navigator.userAgent.toLowerCase();
  for (var i = 0; i < AGENTS.length; i++) {
    var agentStr = AGENTS[i];
    if (agent.indexOf(agentStr) != -1) {
      var versionExpr = new RegExp(agentStr + "[ \/]?([0-9]+(\.[0-9]+)?)");
      var version = 0;
      if (versionExpr.exec(agent) != null) {
        version = parseFloat(RegExp.$1);
      }
      if (agentStr == "opera") 
        return version >= 7;
      if (agentStr == "safari") 
        return version >= 125;
      if (agentStr == "msie") 
        return (version >= 5.5 && agent.indexOf("powerpc") == -1);
      if (agentStr == "netscape") 
        return version > 7;
      if (agentStr == "firefox") 
        return version >= 0.8;
    }
  }
  return !!document.getElementById;
}
function MMMLoad(messages){
  MMMAddMessages(messages);
  if (window.MMMLoadApi)
    MMMLoadApi();
}
function MMMUnload(){
  if (window.MMMUnloadApi) 
    MMMUnloadApi();
}
(function(){
  function isDefined(a) {
    return typeof a != "undefined"
  }
  if (isDefined(window.MMM))
    return;
  else{
    window.MMM = {}
    doConfigMap(window.MMM_Config || {});
  }
  function isUndefined(a) {
    return typeof a == "undefined"
  }
  function isNumber(a) {
    return typeof a == "number"
  }
  function isString(a) {
    return typeof a == "string"
  }
  function isFunction(a){
    return typeof a == "function";
  }
  function isArray(a) {
    return a != null && typeof a == "object" && typeof a.length == "number" && typeof a.slice == "function";
  }
  function isTextNode(node) {
    return node && node.nodeType == 3;
  }
  function isElement(node) {
    return node && node.nodeType == 1;
  }
  function getInstance(someClass) {
    if (!someClass.instance_)
      someClass.instance_ = new someClass;
    return someClass.instance_
  }
  function registerGlobal(name, value) {
    window[name] = value
  };
  function extend(destination, source) {
    for (var property in source)
      destination[property] = source[property];
    return destination;
  };
  function clone(obj){
    return extend({}, obj);
  }
  function doConfigMap(config){
    extend(MMM, config);
  }

  //MMMBrowser
  var AGENTS = ["opera","msie","applewebkit","firefox","camino","mozilla"];
  var OSTypes = ["x11;","macintosh","windows"];
  function MMMBrowserDetector(agent) {
    this.type = -1;
    this.os = -1;
    this.cpu = -1;
    this.version = 0;
    this.revision = 0;
    var agent = agent.toLowerCase();
    for (var i = 0; i < getLength(AGENTS); i++) {
      var agentType = AGENTS[i];
      if (agent.indexOf(agentType) != -1) {
        this.type = i;
        var exp = new RegExp(agentType + "[ /]?([0-9]+(.[0-9]+)?)");
        if (exp.exec(agent))
          this.version = parseFloat(RegExp.$1);
        break
      }
    }
    for (var i = 0; i < getLength(OSTypes); i++) {
      var os = OSTypes[i];
      if (agent.indexOf(os) != -1) {
        this.os = i;
        break
      }
    }
    if (this.os == 1 && agent.indexOf("intel") != -1)
      this.cpu = 0;
    if (this.isMozilla() && /\brv:\s*(\d+\.\d+)/.exec(agent))
      this.revision = parseFloat(RegExp.$1);
    this.browser = this.type;
  }
  MMMBrowserDetector.prototype.isMozilla = function() {
    return this.type == 3 || this.type == 5 || this.type == 4
  };
  MMMBrowserDetector.prototype.isMozillaLegacy = function() {
    return this.type == 5 && this.revision < 1.7
  };
  MMMBrowserDetector.prototype.isMSIELegacy = function() {
    return this.type == 1 && this.version < 7
  };
  MMMBrowserDetector.prototype.isMSIE = function() {
    return (this.type == 1);
  };
  MMMBrowserDetector.prototype.isCssLegacy = function() {
    if (this.type == 1)
      return "CSS1Compat" != this.compatMode(); 
    else 
      return false;
  };
  MMMBrowserDetector.prototype.compatMode = function() {
    return getWithDefault(document.compatMode, "")
  };
  MMMBrowserDetector.prototype.toValue = function() {
    return this.type;
  };

  MMMBrowserDetector.prototype.isOpera = function() {
    return (this.type == 0);
  };

  MMMBrowserDetector.prototype.isSafari = function() {
    return (this.type == 2);
  };

  MMMBrowserDetector.prototype.toString = function(_ver) {
    return (this.type != -1)? (
        this.browser_types[this.type] + (
          (_ver == true && this.version != 0)? this.version: "")
        ) : "unknown";
  };
  MMMBrowserDetector.prototype.isFirefox = function() {
    return (this.type == 3);
  };

  MMMBrowserDetector.prototype.isFirefoxLegacy = function() {
    return (this.type == 3 && this.revision < 1.8);
  };

  MMMBrowser = new MMMBrowserDetector(navigator.userAgent);

  //MMEvent
  function MMMEventManager() {
    this.eventListeners = []
  }
  MMMEventManager.prototype.removeListener = function(listener) {
    var index = listener.getIndex();
    if (index < 0)
      return;
    var tailListener = this.eventListeners.pop();
    if (index < this.eventListeners.length) {
      this.eventListeners[index] = tailListener;
      tailListener.setIndex(index)
    }
    listener.setIndex(-1)
  };
  MMMEventManager.prototype.addListener = function(listener) {
    this.eventListeners.push(listener);
    listener.setIndex(this.eventListeners.length - 1)
  };
  MMMEventManager.prototype.getListeners = function() {
    return this.eventListeners
  };
  MMMEventManager.prototype.clear = function() {
    for (var i = 0; i < this.eventListeners.length; ++i)
      this.eventListeners[i].setIndex(-1);
    this.eventListeners = []
  };
  function addListener(source, eventName, handler) {
    var listener = getInstance(MMMEventListener).make(source, eventName, handler, 0);
    getInstance(MMMEventManager).addListener(listener);
    return listener
  }
  function hasEventListeners(source, eventName) {
    return getLength(findOrAddEventListeners(source, eventName, false)) > 0
  }
  function removeListener(listener) {
    listener.remove();
    getInstance(MMMEventManager).removeListener(listener)
  }
  function clearListeners(source, eventName) {
    trigger(source, "clearlisteners", eventName);
    each(getEventListeners(source, eventName), function(listener) {
        listener.remove();
        getInstance(MMMEventManager).removeListener(listener)
        })
  }
  function clearInstanceListeners(source) {
    trigger(source, "clearlisteners");
    each(getEventListeners(source), function(listener) {
        listener.remove();
        getInstance(MMMEventManager).removeListener(listener)
        })
  }
  function clearAllEventListeners() {
    var sources = [],listeners = getInstance(MMMEventManager).getListeners();
    for (var i = 0,len = getLength(listeners); i < len; ++i) {
      var listener = listeners[i],source = listener.getSource();
      if (!source["__mmmtagged__"]) {
        source["__mmmtagged__"] = true;
        trigger(source, "clearlisteners");
        sources.push(source)
      }
      listener.remove()
    }
    for (var i = 0; i < getLength(sources); ++i) {
      var source = sources[i];
      if (source["__mmmtagged__"])
        try {
          delete source["__mmmtagged__"]
        } catch(ex) {
          source["__mmmtagged__"] = false
        }
    }
    getInstance(MMMEventManager).clear()
  }
  function getEventListeners(source, eventName) {
    var allListeners = [],eListeners = source.__mmmlisteners__;
    if (eListeners)
      if (eventName) {
        if (eListeners[eventName])
          appendSlice(allListeners, eListeners[eventName])
      } else 
        eachForObject(eListeners, function(name, listeners) {
            appendSlice(allListeners, listeners)
            });
    return allListeners
  }
  function findOrAddEventListeners(source, eventName, create) {
    var listeners = null,eListeners = source.__mmmlisteners__;
    if (eListeners) {
      listeners = eListeners[eventName];
      if (!listeners) {
        listeners = [];
        if (create)
          eListeners[eventName] = listeners
      }
    } else {
      listeners = [];
      if (create) {
        source.__mmmlisteners__ = {};
        source.__mmmlisteners__[eventName] = listeners
      }
    }
    return listeners
  }
  function trigger(source, eventName) {
    var args = getSlice(arguments, 2);
    each(getEventListeners(source, eventName), function(listener) {
        try {
        listener.execute(args)
        } catch(e) {
        }
        })
  }
  function addDomListener(source, eventName, handler) {
    var listener;
    if (MMMBrowser.type == 2 && MMMBrowser.version < 419.2 && eventName == "dblclick") {
      source["on" + eventName] = handler;
      listener = getInstance(MMMEventListener).make(source, eventName, handler, 3)
    } else if (source.addEventListener) {
      var useCapture = false;
      if (eventName == "focusin") {
        eventName = "focus";
        useCapture = true
      } else if (eventName == "focusout") {
        eventName = "blur";
        useCapture = true
      }
      var type = useCapture ? 4 : 1;
      source.addEventListener(eventName, handler, useCapture);
      listener = getInstance(MMMEventListener).make(source, eventName, handler, type)
    } else if (source.attachEvent) {
      listener = getInstance(MMMEventListener).make(source, eventName, handler, 2);
      source.attachEvent("on" + eventName, listener.getHandler())
    } else {
      source["on" + eventName] = handler;
      listener = getInstance(MMMEventListener).make(source, eventName, handler, 3)
    }
    if (source != window || eventName != "unload")
      getInstance(MMMEventManager).addListener(listener);
    return listener
  }
  function addDomListenerOnce(source, eventName, handler) {
    var listener = addDomListener(source, eventName, function(){
        removeListener(listener);
        handler.apply(source, arguments);
        });
  }
  function bindDom(source, eventName, obj, method) {
    var handler = callbackDynArgs(obj, method);
    return addDomListener(source, eventName, handler)
  }
  function addClickListener(source, obj, method) {
    var listeners = [];
    listeners.push(bindDom(source, "click", obj, method));
    if (MMMBrowser.type == 1)
      listeners.push(bindDom(source, "dblclick", obj, method));
    return listeners
  }
  function bind(source, eventName, obj, method) {
    return addListener(source, eventName, callback(obj, method))
  }
  function addListenerOnce(source, eventName, method) {
    var listener = addListener(source, eventName, function() {
        removeListener(listener)
        method.apply(source, arguments);
        });
    return listener
  }
  function addListenerCallbackOnce(source, eventName, obj, method) {
    return addListenerOnce(source, eventName, callback(obj, method))
  }
  function addAttachedListener(source, eventName, sourceAttached) {
    return addListener(source, eventName, getTrigger(eventName, sourceAttached))
  }
  function getTrigger(eventName, source) {
    return function() {
      var args = [source,eventName];
      appendSlice(args, arguments);
      trigger.apply(this, args)
    }
  }
  function addAttachDomListener(source, eventName, sourceAttached) {
    return addDomListener(source, eventName, getTrigerArgs(eventName, sourceAttached))
  }
  function getTrigerArgs(eventName, source) {
    return function(args) {
      trigger(source, eventName, args)
    }
  }
  function killEvent(event_) {
    if (event_.type == "click")
      trigger(document, "logclick", event_);
    if (MMMBrowser.type == 1) {
      event_.cancelBubble = true;
      event_.returnValue = false
    } else {
      event_.preventDefault();
      event_.stopPropagation()
    }
  }
  function stopEvent(event_) {
    if (event_.type == "click")
      trigger(document, "logclick", event_);
    if (MMMBrowser.type == 1)
      event_.cancelBubble = true; 
    else 
      event_.stopPropagation()
  }
  function cancelEvent(event_) {
    if (MMMBrowser.type == 1)
      event_.returnValue = false; 
    else 
      event_.preventDefault()
  }
  function MMMEventListener() {
    this.maker = null
  }
  MMMEventListener.prototype.init = function(a) {
    this.maker = a
  };
  MMMEventListener.prototype.make = function(a, b, c, d) {
    if (!this.maker)
      return null; 
    else 
      return new this.maker(a, b, c, d)
  };
  function EventListener(source, eventName, handler, type) {
    this.source = source;
    this.eventName = eventName;
    this.handler = handler;
    this.handler_ = null;
    this.type = type;
    this.index = -1;
    findOrAddEventListeners(source, eventName, true).push(this)
  }
  EventListener.prototype.getHandler = function() {
    var pthis = this;
    return this.handler_ = function(event_) {
      if (!event_)
        event_ = window.event;
      if (event_ && !event_.target)
        try {
          event_.target = event_.srcElement
        } catch(ex) {
        }
      var result = pthis.execute([event_]);
      if (event_ && "click" == event_.type) {
        var source = event_.srcElement;
        if (source && "A" == source.tagName && "javascript:void(0)" == source.href)
          return false
      }
      return result
    }
  };
  EventListener.prototype.remove = function() {
    if (!this.source)
      return;
    switch (this.type) {
      case 1:
        this.source.removeEventListener(this.eventName, this.handler, false);
        break;
      case 4:
        this.source.removeEventListener(this.eventName, this.handler, true);
        break;
      case 2:
        this.source.detachEvent("on" + this.eventName, this.handler_);
        break;
      case 3:
        this.source["on" + this.eventName] = null;
        break
    }
    removeAllFromArray(findOrAddEventListeners(this.source, this.eventName), this);
    this.source = null;
    this.handler = null;
    this.handler_ = null
  };
  EventListener.prototype.getIndex = function() {
    return this.index
  };
  EventListener.prototype.setIndex = function(index) {
    this.index = index
  };
  EventListener.prototype.execute = function(args) {
    if (this.source)
      return this.handler.apply(this.source, args)
  };
  EventListener.prototype.getSource = function() {
    return this.source
  };
  getInstance(MMMEventListener).init(EventListener);
  function pointer(event_){
    return new MMMPoint(
        event_.pageX || (event_.clientX +
          (document.documentElement.scrollLeft || document.body.scrollLeft)),
        event_.pageY || (event_.clientY +
          (document.documentElement.scrollTop || document.body.scrollTop))
        );
  }
  function getEventTarget(a) {
    var b = a.srcElement || a.target;
    if (b && b.nodeType == 3) {
      b = b.parentNode
    }
    return b
  }
  function wheel(event_){          
    var delta = 0;          
    if (!event_) event_ = window.event;          
      if (event_.wheelDelta) {              
        delta = event_.wheelDelta/120;               
        if (window.opera) delta = -delta;          
      }else if (event_.detail) { 
        delta = -event_.detail/3;   
      }  
    return Math.round(delta); //Safari Round      
  }
  Object.extend(MMMEvent, {
    KEY_BACKSPACE: 8,
    KEY_TAB:       9,
    KEY_RETURN:   13,
    KEY_ESC:      27,
    KEY_LEFT:     37,
    KEY_UP:       38,
    KEY_RIGHT:    39,
    KEY_DOWN:     40,
    KEY_DELETE:   46,
    KEY_HOME:     36,
    KEY_END:      35,
    KEY_PAGEUP:   33,
    KEY_PAGEDOWN: 34,
    KEY_IMMMERT:   45
    });
  registerGlobal("MMMEvent", {addListener:addListener,
      addDomListener:addDomListener,removeListener:removeListener,
      clearListeners:clearListeners,clearInstanceListeners:clearInstanceListeners,
      clearNode:clearNode,trigger:trigger,bind:bind,bindDom:bindDom,
      callback:callback,callbackArgs:callbackArgs,addListenerOnce:addListenerOnce,
      addDomListenerOnce:addDomListenerOnce,clearAllEventListeners:clearAllEventListeners,
      cancelEvent:cancelEvent, addAttachDomListener:addAttachDomListener,
      addAttachedListener:addAttachedListener,addClickListener:addClickListener,
      stopEvent:stopEvent, killEvent:killEvent, hasEventListeners:hasEventListeners,
      addListenerCallbackOnce:addListenerCallbackOnce,
      pointer:pointer,target:getEventTarget,stop:killEvent,wheel:wheel});
  registerGlobal("MMMEventListeners", {});
  addDomListener(window, "unload", clearAllEventListeners);
  registerGlobal("MMMUnloadApi", clearAllEventListeners);

  //MMM Messages
  if (isUndefined(MMM.messages))
    MMM.messages = {};
  function addMessages(a){
    var msgs = MMM.messages;
    for (var b in a){
      if (!(b in msgs)){
        msgs[b] = a[b];
      }
    }
  }
  function getMessage(a, default){
    var msgs = MMM.messages;
    if (typeof msgs[a] != "undefined"){
      return msgs[a];
    } else {
      return default || "";
    }
  }
  registerGlobal("MMMAddMessages", addMessages);
  registerGlobal("MMMGetMessage", getMessage);

  if (window.MMMLoad)
    window.MMMLoad();
})()
